package com.service;


import com.facade.base.cud.IBaseFacadeCUD;

import com.mapper.CustomMapper;
import org.springframework.core.ResolvableType;
import tk.mybatis.mapper.entity.Example;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

public abstract class CustomServiceCUD<T> implements IBaseFacadeCUD<T> {

    private Class<T> clz;

    protected abstract CustomMapper<T> initMapper();

    public CustomServiceCUD() {
        ResolvableType resolvableType = ResolvableType.forClass(this.getClass());
        clz = (Class<T>) resolvableType.as(CustomServiceCUD.class).getGeneric(0).resolve();
    }

    @Override
    public T add(T t) {
        initMapper().insert(t);
        return t;
    }

    @Override
    public T addSelective(T t) {
        initMapper().insertSelective(t);
        return t;
    }

    @Override
    public List<T> addBatch(List<T> tList) {
        initMapper().insertList(tList);
        return tList;
    }

    @Override
    public List<T> addSelectiveBatch(List<T> tList) {
        for (T t : tList) {
            initMapper().insertSelective(t);
        }
        return tList;
    }

    @Override
    public T update(T t) {
        initMapper().updateByPrimaryKey(t);
        return t;
    }

    @Override
    public T delete(T t) {
        initMapper().delete(t);
        return t;
    }

    @Override
    public int deleteByPrimaryKey(Serializable id) {
        if (null != id) {
            return initMapper().deleteByPrimaryKey(id);
        }
        return 0;
    }

    @Override
    public int deleteByPropertyEqualTo(String property, Object value) {
        Example example = new Example(clz);
        Example.Criteria criteria = example.createCriteria();
        if (null == value) {
            criteria.andIsNull(property);
        } else {
            criteria.andEqualTo(property, value);
        }
        return initMapper().deleteByExample(example);
    }

    @Override
    public int deleteByPropertiesEqualTo(Map<String, Object> propertyValue) {
        if (null == propertyValue || 0 == propertyValue.size()) {
            return 0;
        }
        Example example = new Example(clz);
        Example.Criteria criteria = example.createCriteria();
        Set<Map.Entry<String, Object>> entrySet = propertyValue.entrySet();
        String property;
        Object value;
        for (Map.Entry<String, Object> entry : entrySet) {
            property = entry.getKey();
            value = entry.getValue();
            if (null == value) {
                criteria.andIsNull(property);
            } else {
                criteria.andEqualTo(property, value);
            }
        }
        return initMapper().deleteByExample(example);
    }

    @Override
    public int deleteByPropertiesEqualToAndIn(Map<String, Object> propertyValue) {
        if (null == propertyValue || 0 == propertyValue.size()) {
            return 0;
        }
        Example example = new Example(clz);
        Example.Criteria criteria = example.createCriteria();
        Set<Map.Entry<String, Object>> entrySet = propertyValue.entrySet();
        String property;
        Object value;
        for (Map.Entry<String, Object> entry : entrySet) {
            property = entry.getKey();
            value = entry.getValue();
            if (null == value) {
                criteria.andIsNull(property);
            } else if (value instanceof Collection) {
                criteria.andIn(property, (Collection<?>) value);
            } else {
                criteria.andEqualTo(property, value);
            }
        }
        return initMapper().deleteByExample(example);
    }

    @Override
    public int deleteByPropertyNotEqualTo(String property, Object value) {
        Example example = new Example(clz);
        Example.Criteria criteria = example.createCriteria();
        if (null == value) {
            criteria.andIsNotNull(property);
        } else {
            criteria.andNotEqualTo(property, value);
        }
        return initMapper().deleteByExample(example);
    }

    @Override
    public int deleteByPropertyIn(String property, List<?> params) {
        Example example = new Example(clz);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn(property, params);
        return initMapper().deleteByExample(example);
    }

    @Override
    public int deleteByPropertyNotIn(String property, List<?> params) {
        Example example = new Example(clz);
        Example.Criteria criteria = example.createCriteria();
        criteria.andNotIn(property, params);
        return initMapper().deleteByExample(example);
    }

    @Override
    public int deleteAll() {
        return initMapper().deleteByExample(null);
    }
}